package de.tum.in.eist.poll.client.gui;

import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.VerticalPanel;

import de.tum.in.eist.poll.shared.Feedback;
import de.tum.in.eist.poll.shared.Lecture;
import de.tum.in.eist.poll.shared.User;

public class LectureWidget extends WidgetContainer {

	// GUI
	private LectureChartWidget chart;
	private Label topic;
	private Label date;
	private LectureVotePanel votePanel;
	private Button submitButton;
	private Label errorLabel;
	private HorizontalPanel headerPanel;
	private VerticalPanel contentPanel;
	private HorizontalPanel submitPanel;
	private VerticalPanel mainPanel;

	// Local
	private Lecture lecture;
	private User user;
	private boolean minimized;

	public LectureWidget(User user, Lecture lecture, boolean notification) {
		super(true, false);
		this.lecture = lecture;
		this.user = user;
		init();
		addContent();
		update(lecture);
		if (notification)
			addNotification();
	}

	/**
	 * initialize the objects
	 */
	private void init() {
		// GUI
		topic = new Label();
		date = new Label();
		chart = new LectureChartWidget(lecture.getStats());
		submitButton = new Button("Submit");
		headerPanel = new HorizontalPanel();
		contentPanel = new VerticalPanel();
		mainPanel = new VerticalPanel();

		// Local
		minimized = true;

		// Add styles
		mainPanel.addStyleName("lectureForm");
		headerPanel.addStyleName("containerPanelForm");
		contentPanel.addStyleName("containerPanelForm");
		topic.addStyleName("lectureTopic");
		date.addStyleName("lectureDate");
	}

	public void update(Lecture lecture) {
		this.lecture = lecture;
		topic.setText(lecture.getTopic());
		date.setText(lecture.getStringDate());
	}

	/**
	 * actualize the chart with the new statistics
	 * @param lecture
	 */
	public void updateChart(int[] stats) {
		if (chart.isVisible()) {
			chart.update(stats, "");
		}
	}

	/**
	 * Add topic, date, chart, ... to the widget
	 */
	private void addContent() {
		// Topic of the lecture
		headerPanel.add(topic);

		// Date of the lecture
		headerPanel.add(date);

		// Content
		contentPanel.add(chart);
		chart.setVisible(false);

		// Header
		mainPanel.add(headerPanel);
		add(mainPanel);

		// Student
		if (user.isStudent()) {
			// Lecture Chart
			if (lecture.userHasRatedLecture(user.getKey())) {
				// addChart();
				chart.setVisible(true);
			}
			// VotePanel
			else {
				addVotePanel();
			}
		}

		// Teacher
		if (user.isLecturer()) {
			// Lecture Chart
			// addChart();
			chart.setVisible(true);
			// Vote result, positive and negative
			addVoteResult();
		}

		// Add content panel
		mainPanel.add(contentPanel);
		contentPanel.setVisible(false);

		// Expand the lecture view if minimized is false
		if (!minimized) {
			expand();
		}
	}

	// /**
	// * Add the chart to the lecture view
	// */
	// private void addChart() {
	// chart.setVisible(true);
	// }

	/**
	 * Add the vote panel to the the lecture view
	 */
	private void addVotePanel() {
		if (votePanel == null)
			initVotePanel();
		submitPanel.add(errorLabel);
		submitPanel.add(submitButton);
		contentPanel.add(votePanel);
		contentPanel.add(submitPanel);
	}

	/**
	 * Create an panel to rate the lecture
	 */
	private void initVotePanel() {
		votePanel = new LectureVotePanel(lecture.hashCode());
		submitPanel = new HorizontalPanel();
		errorLabel = new Label("");
		errorLabel.addStyleName("errorLabel");
		submitButton.addStyleName("standardButton");
	}

	/**
	 * Add the vote results in a table wit a positive and negative column to the
	 * lecture view
	 */
	private void addVoteResult() {
		FlexTable table = new FlexTable();
		table.setText(0, 0, "Positive");
		table.setText(0, 1, "Negative");
		table.addStyleName("lectureTable");
		table.getRowFormatter().addStyleName(0, "lectureTableHeader");
		table.getColumnFormatter().addStyleName(0, "lectureTableColoumn");
		table.getColumnFormatter().addStyleName(1, "lectureTableColoumn");

		int i = 1;
		for (Feedback f : lecture.getFeedbacks()) {
			// a poitive or negative answer exist add a new row
			if (!f.getPositiveAnswer().equals("")
					|| !f.getNegativeAnswer().equals("")) {				
				table.setText(i, 0, f.getPositiveAnswer());
				table.setText(i, 1, f.getNegativeAnswer());
				// change every second row style
				if (i % 2 == 0) {
					table.getRowFormatter().addStyleName(i, "lectureTableRow1");
				} else {
					table.getRowFormatter().addStyleName(i, "lectureTableRow2");
				}
				i++;
			}
		}
		if (table.getRowCount() > 1) {
			contentPanel.add(table);
		}
	}

	/**
	 * Maximize the lecture view and show: headline and chart or vote panel
	 */
	public void expand() {
		contentPanel.removeStyleName("closed");
		contentPanel.addStyleName("open");
		minimized = false;
		contentPanel.setVisible(true);
	}

	/**
	 * Minimize the lecture view, just show the headline
	 */
	public void collapse() {
		contentPanel.removeStyleName("lectureWidget.open");
		contentPanel.addStyleName("lectureWidget.closed");
		minimized = true;
		contentPanel.setVisible(false);
	}

	/**
	 * Mark this lecture view as updated.
	 */
	public void addNotification() {
		mainPanel.addStyleName("lectureNotification");
		addHideButton();
	}

	/**
	 * Unmark this lecture view as updated
	 */
	public void hideNotification() {
		user.clearNotification(lecture);
		removeHideButton();
		mainPanel.removeStyleName("lectureNotification");
	}

	/**
	 * remove vote panel and submit button and add the chart instead
	 */
	public void removeVotePanel() {
		collapse();
		contentPanel.remove(votePanel);
		contentPanel.remove(submitPanel);
		// addChart();
		chart.setVisible(true);
		expand();
	}

	public LectureVotePanel getVotePanel() {
		return votePanel;
	}

	public Lecture getLecture() {
		return lecture;
	}

	public User getUser() {
		return user;
	}

	public boolean isMinimized() {
		return minimized;
	}

	public void setMinimized(boolean minimized) {
		this.minimized = minimized;
	}

	public Button getSubmitButton() {
		return submitButton;
	}

	public Label getTopic() {
		return topic;
	}

	public Label getErrorLabel() {
		return errorLabel;
	}
}
